package com.cnt.controller;

import com.cnt.controller.convertor.StringToDateConverter;
import com.cnt.dto.DonationsDTO;
import com.cnt.entity.*;

import com.cnt.service.*;
import com.cnt.vo.ResultVo;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/api/donation")
public class DonationController {

    private final ModelMapper modelMapper;

    @Autowired
    private PointsService pointsService;

    @Autowired
    public DonationController(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
        this.modelMapper.addConverter(new StringToDateConverter("yyyy/MM/dd"));
    }

    @Autowired
    private DonationsService donationsService;
    @Autowired
    private DonationsInfoService donationsInfoService;
    @Autowired
    private DonationRecordsService donationRecordsService;
    @Autowired
    private DonationRequestService donationRequestService;

    //募捐大厅的返回的募捐单
    @GetMapping("/list")
    public ResultVo<List<Donations>> queryDonations( @RequestParam(required = false) Integer minAge,
                                                     @RequestParam(required = false) Integer oldAge,
                                                     @RequestParam(required = false) String name){
        if(minAge==null){
            minAge = 0;
        }
        if(oldAge == null){
            oldAge = 150;
        }
        return donationsService.queryDonations(minAge,oldAge,name);
    }

    //查询个人的募捐单时返回的
    @PostMapping("/queryDonationByPersonId")
    public ResultVo<List<Donations>> queryDonationByPersonId(@RequestBody Persons persons) {
        return donationsService.queryDonationByPersonId(persons.getPersonId());
    }
    @PostMapping("/create")
    public ResultVo<Donations> createDonation(@RequestBody DonationsDTO dto) {
        Donations donations = modelMapper.map(dto, Donations.class);
        return donationsService.insert(donations);
    }
    @GetMapping("/get")
    public ResultVo<Donations> getDonation(@RequestParam Integer donationId) {
        return donationsService.getByDonationId(donationId);
    }
    @PutMapping("/update")
    public ResultVo<Donations> updateDonation(@RequestBody DonationsDTO dto) { //TODO
        System.out.println(dto.getDeadline()+"+++++");
        Donations donations = modelMapper.map(dto, Donations.class);
        return donationsService.updateDonation(donations);
    }

    @DeleteMapping("/delete")
    public ResultVo<String> deleteDonationById(@RequestParam Integer donationId) {
        System.out.println(donationId);
        return donationsService.deleteDonationById(donationId);
    }

    @PostMapping("/submit")
    public ResultVo<Donations> submitDonation(@RequestBody Donations donations) {
        return donationsService.submitDonation(donations);
    }


    @PostMapping("/revoke")
    public ResultVo<Donations> revokeDonation(@RequestParam Integer donationId) {
        return donationsService.revokeDonation(donationId);
    }

    @PostMapping("/updateDetails")
    public ResultVo<DonationsInfo> updateDetails(@RequestBody DonationsInfo donationsInfo) {

        return donationsInfoService.updateDetails(donationsInfo);
    }


    @PostMapping("/uploadData")
    public ResultVo<String> uploadDonationData(@RequestParam("file") MultipartFile file,
                                               @RequestParam("donationId") Integer donationId) {
        return donationsInfoService.uploadData(donationId, file);
    }

    @PostMapping("/uploadDonationImage")
    public ResultVo<String> uploadDonationImage(@RequestParam("file") MultipartFile file,
                                                @RequestParam("donationId") Integer donationId) {
        return donationsService.uploadDonationImage(donationId, file);
    }

    //指定了响应的Content-Type为二进制流。这告诉客户端返回的数据是一个二进制文件
    @GetMapping(value = "/downloadScoreSheet", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<Resource> downloadScoreSheet() throws Exception {
        // 读取募捐积分表文件
        Resource fileResource = new ClassPathResource("static/ss.xlsx");
        InputStream inputStream = fileResource.getInputStream();

        // 构造响应头
        HttpHeaders headers = new HttpHeaders();
        //设置响应的 Content-Type 为二进制流
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //设置响应的 Content-Disposition 头部，指定文件作为附件下载，并指定下载的文件名
        headers.setContentDispositionFormData("attachment", "ss.xlsx");

        // 返回文件流
        InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
        return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
    }

    @GetMapping("/downloadDataTemplate")
    public ResponseEntity<Resource> downloadDataTemplate() throws Exception {
        // 加载募捐资料模板文件
        ClassPathResource templateFile = new ClassPathResource("static/ss.xlsx");

        // 创建输入流资源
        InputStreamResource inputStreamResource = new InputStreamResource(templateFile.getInputStream());

        // 设置响应头信息
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=ss.xlsx");

        // 返回包含输入流资源和响应头信息的ResponseEntity对象
        return ResponseEntity.ok()
                .headers(headers)
                .body(inputStreamResource);
    }

    @GetMapping("/getDonationsInfo")
    public ResultVo<DonationsInfo> getDonationIdInfo(@RequestParam Integer donationId) {
        return donationsInfoService.getDonationsInfo(donationId);
    }

    @GetMapping("/getDonationRecords")
    public ResultVo<List<DonationRecords>> getDonationRecords(@RequestParam Integer donationId){
        return donationRecordsService.getDonationRecords(donationId);
    }

    @GetMapping("/getPointsRule")
    public ResultVo<List<PointsRules>> getPointsRuleByRequest(@RequestParam Integer requestId){
        return donationRequestService.getPointsRuleByRequest(requestId);
    }

    @PostMapping("/setPointsRule")
    public ResultVo<List<PointsRules>> setPointsRuleByDonation(@RequestBody Donations donations){
        return donationRequestService.setPointsRuleByDonation(donations.getDonationId(),
                donations.getIsPointsRules());
    }

    @GetMapping(value = "/downloadData", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<byte[]> downloadData(@RequestParam(value="donationId", required=false) Integer donationId) {

        try (BufferedInputStream bis = new BufferedInputStream(donationsService.download(donationId), 4096)) {
            byte[] data = new byte[bis.available()];
            bis.read(data);
            if(data.length==0){
                return ResponseEntity.status(500).body(null);
            }
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=personFile.pdf")
                    .body(data);
        } catch (Exception e) {
            return ResponseEntity.status(500).body(null);
        }
    }

    @GetMapping("/getByIsPointsRules")
    public ResultVo<List<PointsRules>> getByIsPointsRules(@RequestParam(value="isPointsRules", required=false) String isPointsRules){
        if(Objects.equals(isPointsRules, null))
            return new ResultVo<>(1,"没有完成积分表的填写",null);
        return pointsService.getByIsPointsRules(isPointsRules);
    }

    @GetMapping("/getPoints")
    ResultVo<List<PointsRules>> getPoints(@RequestParam Integer pointsId){
        return pointsService.getPoints(pointsId);
    }
}
